#include <bits/stdc++.h>
using namespace std;

void key(string c)
{
    int klen = 1;         //密钥长度
    int clen = c.size(); //密文的长度
    while (1)
    {
        float IC[klen];                //重合指数
        float avgIC = 0;               //平均重合指数
        for (int i = 0; i < klen; i++) //统计分组字母个数
        {
            int out[26] = {0}; //盛放字母个数的数组
            for (int j = 0; i + j * klen < clen; j++)
                out[(int)(c[i + j * klen] - 'A')]++;
            float e = 0.000f;
            int L = 0;
            for (int k = 0; k < 26; k++) //子串密文长度
                L += out[k];
            L *= (L - 1);
            for (int k = 0; k < 26; k++) //分组计算重合指数IC
                if (out[k] != 0)
                    e = e + ((float)out[k] * (float)(out[k] - 1)) / (float)L;
            IC[i] = e;
        }
        for (int i = 0; i < klen; i++)
            avgIC += IC[i];
        avgIC /= klen; //求IC的平均值
        if (avgIC >= 0.06)
            break; //判断退出条件，重合指数的平均值是否大于0.06
        else
            klen++;
    }
    cout << "密钥长度为：" << klen << endl;

    float p[] = {0.082, 0.015, 0.028, 0.043, 0.127, 0.022, 0.02, 0.061, 0.07, 0.002, 0.008, 0.04, 0.024, 0.067, 0.075, 0.019, 0.001, 0.06, 0.063, 0.091, 0.028, 0.01, 0.023, 0.001, 0.02, 0.001};

    int key[100] = {0};            //存放密钥
    for (int i = 0; i < klen; i++) //统计分组字母个数
    {
        int g = 0; //密文移动g个位置
        for (int t = 0; t < 26; t++)
        {
            float x = 0.000f;  //拟重合指数
            int out[26] = {0}; //盛放字母个数的数组
            for (int j = 0; i + j * klen < clen; j++)
                out[(int)(c[i + j * klen] - 'A')]++;
            int L = 0;
            for (int k = 0; k < 26; k++) //子串密文长度
                L += out[k];
            for (int k = 0; k < 26; k++)
                x = x + p[k] * out[(k + g) % 26];
            if (x / L > 0.055)
            {
                key[i] = g;
                break;
            }
            else
                g++;
        }
    }
    cout << "加密密钥为：";
    for (int i = 0; i < klen; i++) //输出密钥字
        cout << char('a' + key[i]);
    cout << endl;
}

int main()
{
    string str = "AIGWDGAENFEFQTAUGSRNOSTHYAOPEDLHENLEOLEMOCBCLNDSMESOKYHNNSOSNTOWNROUOFEDZHKHIHOMGEPSRAIRNNNRSRSNGTOFEERYSFCRPMHYFELRULNFOIUENEAOAREMMIHMOEAHOIANETDINTLSGFELEYINESCDDLBHDOOAIATFOTIXNSHLTRDNENITYRAOPCAMSEUDALONUZUAUDEAIELHHNTFFAENYDRTMOAOEEKDOIYRMYFTOEDNERSFISYHETKIPTTDGZRDETULHSUGOIBNOLAVANI";
    key(str);
    return 0;
}